<?php
/**
 * @reference https://github.com/phpredis/phpredis
 * @description
 * @date 2015/11/26  14:54
 * @version    1.0
 * @modify
 */
namespace lib;


class RedisDB
{
    protected static $_instance;
    protected $db;

    public function __construct($host, $pass, $port = 6379)
    {
        $this->pconnect($host, $pass, $port);
    }

    public static function getInstance($host, $pass, $port = 6379)
    {
        if (static::$_instance === null) {
            static::$_instance = new static($host, $pass, $port);
        }
        return static::$_instance;
    }

    public function connect($host, $pass, $port)
    {

        $this->db = new \Redis();
        $this->db->connect($host, $port);
        $this->db->auth($pass);
    }

    /**
     * redis 长连接
     */
    public function pconnect($host, $pass, $port)
    {
        $this->db = new \Redis();
        $this->db->connect($host, $port);
        $this->db->auth($pass);
    }

    /**
     * 如果key不存在，设置持久存在的key，存在覆盖原来的key值
     * For example,
     * $redis->set("name","qiqi");
     *
     * @param $key
     * @param $value
     */
    public function set($key, $value)
    {
        $this->db->set($key, $value);
    }

    /**
     * 如果key不存在，设置持久存在的key，存在则不做任何操作
     * For example,
     * $redis->setnx("name","qiqi");
     *
     * @param $key
     * @param $value
     */
    public function setnx($key, $value)
    {
        $this->db->setnx($key, $value);
    }

    /**
     * 设置有生存时间的key
     * For example,
     * $redis->setex("name","qiqi",3600);
     *
     * @param $key
     * @param $value
     * @param int $ttl
     */
    public function setex($key, $value, $ttl = 86400)
    {
        $this->db->setex($key, $ttl, $value);
    }


    public function del($key1)
    {
        $this->db->del($key1);
    }

    /**
     * APPEND key value
     * 如果key已经存在并且是一个字符串，APPEND命令将value追加到key原来的值之后。
     * 如果key不存在，APPEND就简单地将给定key设为value，就像执行SET key value一样。
     * 追加value之后，key中字符串的长度。
     * For example,
     * $redis->append("name","qiqi");
     *
     * @param $key
     * @param $value
     * @param int $ttl
     */
    public function append( $key, $value )
    {
        $this->db->append( $key, $value );
    }

    /**
     * STRLEN key
     * 返回key所储存的字符串值的长度。当key储存的不是字符串值时，返回一个错误。字符串值的长度。当 key不存在时，返回0。
     * For example,
     * $redis->strlen("name");
     *
     * @param $key
     * @param $value
     * @param int $ttl
     */
    public function strlen( $key )
    {
        $this->db->strlen( $key );
    }

    /**
     * INCR key
     * 将key中储存的数字值增一。
     * 如果key不存在，以0为key的初始值，然后执行INCR操作。如果值包含错误的类型，或字符串类型的值不能表示为数字，那么返回一个错误。
     * For example,
     * $redis->incr("name",3600);
     *
     * @param $key
     * @param $value
     * @param int $ttl
     * @return 执行INCR命令之后key的值。
     */
    public function incr( $key )
    {
        $this->db->incr( $key );
    }

    /**
     * DECR key
     * 将key中储存的数字值减一。
     * 如果key不存在，以0为key的初始值，然后执行INCR操作。如果值包含错误的类型，或字符串类型的值不能表示为数字，那么返回一个错误。
     * For example,
     * $redis->decr("name",3600);
     *
     * @param $key
     * @param $value
     * @param int $ttl
     * @return 执行INCR命令之后key的值。
     */
    public function decr( $key )
    {
        $this->db->decr( $key );
    }

    /**
     * INCRBY key increment
     * 将key所储存的值加上增量increment。
     * 如果key不存在，以0为key的初始值，然后执行INCRBY命令。如果值包含错误的类型，或字符串类型的值不能表示为数字，那么返回一个错误。
     * For example,
     * $redis->incrBy("name",3600);
     *
     * @param $key
     * @param $value
     * @param int $ttl
     * @return 加上increment之后，key的值。
     */
    public function incrBy( $key, $value )
    {
        $this->db->incrBy( $key, $value );
    }

    /**
     * DECRBY key decrement
     * 将key所储存的值减去减量increment。
     * 如果key不存在，以0为key的初始值，然后执行INCRBY命令。如果值包含错误的类型，或字符串类型的值不能表示为数字，那么返回一个错误。
     * For example,
     * $redis->decrBy("name",3600);
     *
     * @param $key
     * @param $value
     * @param int $ttl
     * @return 加上increment之后，key的值。
     */
    public function decrBy( $key, $value )
    {
        $this->db->decrBy( $key, $value );
    }

    /**
     * 判断key是否存在
     * For example,
     * $redis->exists("qiqi")
     *
     * @param $key
     * @return boolean
     */
    public function exists($key)
    {
        return $this->db->exists($key);
    }

    /**
     * 返回 key 所关联的字符串值
     * for example,
     * $redis->get("qiqi")
     *
     * @param $key
     * @return mixed
     */
    public function get($key)
    {
        return $this->db->get($key);
    }

    /**
     * 删除指定key
     * For example,
     * $redis->delete("qiqi")
     * $redis->delete(["a","b"])
     *
     * @param str|array $key
     */
    public function delete($key)
    {
        $this->db->delete($key);
    }

    /**
     * 以秒为单位，返回给定 key 的剩余生存时间
     * 当 key 不存在时，返回 -2
     * 当 key 存在但没有设置剩余生存时间时，返回 -1
     * For example,
     * $redis->ttl("qiqi")
     *
     * @param $key
     */
    public function ttl($key)
    {
        $this->db->ttl($key);
    }

    /**
     * value 值按从左到右的顺序依次插入到表头
     * For example,
     * $redis->setQueue("queue",1)
     *
     * @param $key
     * @param $value
     */
    public function setQueue($key, $value)
    {
        $this->db->lPush($key, $value);
    }

    /**
     * RPUSH key value [value ...]
     * 将一个或多个值value插入到列表key的表尾。如果有多个value值，那么各个value值按从左到右的顺序依次插入到表尾
     * 比如对一个空列表(mylist)执行RPUSH mylist a b c，则结果列表为a b c，等同于执行命令RPUSHmylist a、RPUSH mylist b、RPUSH mylist c。
     * 如果key不存在，一个空列表会被创建并执行RPUSH操作。当key存在但不是列表类型时，返回一个错误。
     * For example,
     * $redis->rPush("queue",1)
     *
     * @param $key
     * @param $value
     */
    public function rPush($key, $value)
    {
        $this->db->rPush($key, $value);
    }

    /**
     * 阻塞弹出队列开头的元素
     * For example,
     * do{
     *    $task=$redis->getQueue($key);
     *    if($task[1]){
     *        echo $task[1];
     *    }
     * }while(true);
     *
     * @param $key
     * @param int $timeout
     * @return array
     */
    public function getQueue($key, $timeout = 30)
    {
        return $this->db->brPop($key, $timeout);
    }

    /**
     * LPOP key
     * 移除并返回列表key的头元素。
     * For example,
     * $redis->lPop("queue")
     * @param $key
     * @param int $timeout
     * @return 列表的头元素。当key不存在时，返回nil。
     */
    public function lPop($key)
    {
        return $this->db->lPop($key);
    }

    /**
     * RPOP key
     * 移除并返回列表key的尾元素。
     * For example,
     * $redis->rPop("queue")
     * @param $key
     * @return 列表的尾元素。当key不存在时，返回nil。
     */
    public function rPop($key)
    {
        return $this->db->rPop($key);
    }

    /**
     * LLEN key
     * 返回列表key的长度。如果key不存在，则key被解释为一个空列表，返回0.如果key不是列表类型，返回一个错误。
     * For example,
     * $redis->lLen("queue")
     * @param $key
     * @return 列表key的长度。
     */
    public function lLen($key)
    {
        return $this->db->lLen($key);
    }

    /**
     * LINDEX key index
     * 返回列表key中，下标为index的元素。下标(index)参数start和stop都以0为底，也就是说，以0表示列表的第一个元素，以1表示列表的第二个元素，以此类推。
     * 你也可以使用负数下标，以-1表示列表的最后一个元素，-2表示列表的倒数第二个元素，以此类推。如果key不是列表类型，返回一个错误。
     * For example,
     * $redis->lLen("queue")
     * @param $key
     * @return 列表中下标为index的元素。如果index参数的值不在列表的区间范围内(out of range)，返回nil。
     */
    public function lIndex( $key, $index )
    {
        return $this->db->lIndex( $key, $index );
    }

    /**
     * LREM key count value
     * 根据参数count的值，移除列表中与参数value相等的元素。
     * 删除count个名称为key的list中值为value的元素。
     * count为0，删除所有值为value的元素，count>0从头至尾删除count个值为value的元素，count<0从尾到头删除|count|个值为value的元素
     * For example,
     * $redis->lRem("queue"，'s',2)
     * @param $key
     * @return 被移除元素的数量。因为不存在的key被视作空表(empty list)，所以当key不存在时，LREM命令总是返回0。
     */
    public function lRem( $key, $value, $count )
    {
        return $this->db->lRem( $key, $value, $count );
    }

    /**
     * LTRIM key start stop
     * 对一个列表进行修剪(trim)，就是说，让列表只保留指定区间内的元素，不在指定区间之内的元素都将被删除。
     * 举个例子，执行命令LTRIM list 0 2，表示只保留列表list的前三个元素，其余元素全部删除。下标(index)
     * 参数start和stop都以0为底，也就是说，以0表示列表的第一个元素，以1表示列表的第二个元素，以此类推。
     * 你也可以使用负数下标，以-1表示列表的最后一个元素，-2表示列表的倒数第二个元素，以此类推。
     * 当key不是列表类型时，返回一个错误。
     * 如果start下标比列表的最大下标end(LLEN list减去1)还要大，或者start > stop，LTRIM返回一个空列表(因为LTRIM已经将整个列表清空)。
     * 如果stop下标比end下标还要大，Redis将stop的值设置为end。
     * For example,
     * $redis->lTrim( "queue"，0,2 )
     * @param $key
     * @return 命令执行成功时，返回ok。
     */
    public function lTrim( $key, $start, $stop )
    {
        return $this->db->lTrim( $key, $start, $stop );
    }

    /**
     * 获取队列数据
     * For example,
     * $re = $redis->Lrange('ming',0,10);
     *
     * @param $key
     * @param start
     * @param end
     * @return array
     */
    public function Lrange($key, $start, $end)
    {
        return $this->db->Lrange($key, $start, $end);
    }

    /**
     * 订阅频道
     * For example,
     *
     * @param $key
     * @return array
     */
    public function setChannel($key)
    {
        return $this->db->SUBSCRIBE($key);
    }

    /**
     * 向集合中添加元素
     * For example,
     *
     * @param $key
     * @param value1
     * @return array
     */
    public function sAdd($key, $value1)
    {
        return $this->db->sAdd($key, $value1);
    }

    /**
     * 查看集合中添加元素
     * For example,
     * $res = $redis->sMembers('xiaoming');
     * @param $key
     * @return array 所有的值
     */
    public function sMembers($key)
    {
        return $this->db->sMembers($key);
    }

    /**
     * 移除集合中元素
     * For example,
     * $ress = $redis->sRemove('testset','1');
     * @param $key
     * @param $value
     * @return array 所有的值
     */
    public function sRemove($key,$value)
    {
        return $this->db->sRemove($key,$value);
    }

    /**
     * 查看集合中是否有该元素
     * For example,
     * $ress = $redis->sIsMember('testset','sssss');
     * @param $key
     * @param $value
     * @return true 所有的值
     */
    public function sIsMember($key,$value)
    {
        return $this->db->sIsMember($key,$value);
    }

    /**
     * 查看集合中元素的数量
     * For example,
     * $ress = $redis->sSize('testset');
     * @param $key
     * @return true 所有的值
     */
    public function sSize($key)
    {
        return $this->db->sSize($key);
    }

    /**
     * 返回集合key的基数(集合中元素的数量)。
     * For example,
     * $ress = $redis->sCard('testset');
     * @param $key
     * @return true 集合的基数。当key不存在时，返回0。
     */
    public function sCard($key)
    {
        return $this->db->sCard($key);
    }

    /**
     * SMOVE source destination member
     * 将member元素从source集合移动到destination集合
     * For example,
     * $ress = $redis->sMove('testset','xiaoming','sssss');
     * @param $srcKey
     * @param $dstKey
     * @param $member
     * @return 如果member元素被成功移除，返回1。
     * 如果member元素不是source集合的成员，并且没有任何操作对destination集合执行，那么返回0
     */
    public function sMove($srcKey, $dstKey, $member)
    {
        return $this->db->sMove($srcKey, $dstKey, $member);
    }

    /**
     * 返回集合中的一个随机元素。
     * For example,
     * //$ress = $redis->sRandMember('testset');
     * @param $srcKey
     * @return 被选中的随机元素。 当key不存在或key是空集时，返回nil。
     */
    public function sRandMember($key)
    {
        return $this->db->sRandMember($key);
    }

    /**
     * 返回一个集合的全部成员，该集合是所有给定集合的交集。
     * 不存在的key被视为空集。
     * For example,
     * //$ress = $redis->sInter('testset','xiaoming');
     * @param $srcKey
     * @return 被选中的随机元素。 当key不存在或key是空集时，返回nil。
     */
    public function sInter($key1, $key2)
    {
        return $this->db->sInter($key1, $key2);
    }

    /**
     * 此命令等同于SINTER，但它将结果保存到destination集合，而不是简单地返回结果集。
     * 如果destination集合已经存在，则将其覆盖。
     * For example,
     * $ress = $redis->sInterStore('name','testset','xiaoming');
     * @param $srcKey
     * @return 结果集中的成员数量。 O(N * M)
     */
    public function sInterStore($dstKey,$key1, $key2)
    {
        return $this->db->sInterStore($dstKey,$key1, $key2);
    }

     /**
     * 返回一个集合的全部成员，该集合是所有给定集合的并集。
     * 不存在的key被视为空集。
     * For example,
     * //$ress = $redis->sUnion('testset','xiaoming');
     * @param $srcKey
     * @return 被选中的随机元素。 当key不存在或key是空集时，返回nil。
     */
    public function sUnion($key1, $key2)
    {
        return $this->db->sUnion($key1, $key2);
    }

    /**
     * 此命令等同于SUNION，但它将结果保存到destination集合，而不是简单地返回结果集。
     * 如果destination集合已经存在，则将其覆盖。
     * For example,
     * $ress = $redis->sInterStore('name','testset','xiaoming');
     * @param $srcKey
     * @return 结果集中的成员数量。 O(N * M)
     */
    public function sUnionStore($dstKey,$key1, $key2)
    {
        return $this->db->sUnionStore($dstKey,$key1, $key2);
    }

    /**
     * 返回一个集合的全部成员，该集合是所有给定集合的差集 。
     * 不存在的key被视为空集。
     * For example,
     * //$ress = $redis->sDiff('testset','xiaoming');
     * @param $srcKey
     * @return 被选中的随机元素。 当key不存在或key是空集时，返回nil。
     */
    public function sDiff($key1, $key2)
    {
        return $this->db->sDiff($key1, $key2);
    }

    /**
     * 此命令等同于SDIFF，但它将结果保存到destination集合，而不是简单地返回结果集。
     * 如果destination集合已经存在，则将其覆盖。
     * For example,
     * $ress = $redis->sDiffStore('name','testset','xiaoming');
     * @param $srcKey
     * @return 结果集中的成员数量。 O(N * M)
     */
    public function sDiffStore($dstKey,$key1, $key2)
    {
        return $this->db->sDiffStore($dstKey,$key1, $key2);
    }


    /**
     * ZADD key score member [[score member] [score member] ...]
     将一个或多个member元素及其score值加入到有序集key当中。
     如果某个member已经是有序集的成员，那么更新这个member的score值，并通过重新插入这个member元素，来保证该member在正确的位置上。
     score值可以是整数值或双精度浮点数。
     如果key不存在，则创建一个空的有序集并执行ZADD操作。
     当key存在但不是有序集类型时，返回一个错误。
     * For example,
     *
     * @param $key
     * @param value1
     * @return array 被成功添加的新成员的数量，不包括那些被更新的、已经存在的成员。
     */
    public function zAdd( $key, $score1, $value1)
    {
        return $this->db->zAdd($key, $score1, $value1);
    }

    /**
     * 移除有序集key中的一个或多个成员，不存在的成员将被忽略。
     * 当key存在但不是有序集类型时，返回一个错误。
     * For example,
     * $ress = $redis->zRem('ming','1');
     * @param $key
     * @param $value
     * @return array 被成功移除的成员的数量，不包括被忽略的成员。
     */
    public function zRem($key,$value)
    {
        return $this->db->zRem($key,$value);
    }

    /**
     * 返回有序集key中，指定区间内的成员。
     * 其中成员的位置按score值递增(从小到大)来排序。
     * 具有相同score值的成员按字典序(lexicographical order)来排列。
     * 如果你需要成员按score值递减(从大到小)来排列，请使用ZREVRANGE命令。
     * 下标参数start和stop都以0为底，也就是说，以0表示有序集第一个成员，以1表示有序集第二个成员，以此类推。
     * 你也可以使用负数下标，以-1表示最后一个成员，-2表示倒数第二个成员，以此类推。
     * 超出范围的下标并不会引起错误。
     * 比如说，当start的值比有序集的最大下标还要大，或是start > stop时，ZRANGE命令只是简单地返回一个空列表。
     * 另一方面，假如stop参数的值比有序集的最大下标还要大，那么Redis将stop当作最大下标来处理。
     * 可以通过使用WITHSCORES选项，来让成员和它的score值一并返回，返回列表以value1,score1, ..valueN,scoreN的格式表示。
     * 客户端库可能会返回一些更复杂的数据类型，比如数组、元组等。
     * For example,
     * $re = $redis->zRange('ming',0,10);
     *
     * @param $key
     * @param $start
     * @param $end
     * @param $options Two options are available:
     *                      - withscores => TRUE,
     *                      - and limit => array($offset, $count)
     * @return array
     */
    public function zRange($key, $start, $end , $withscores = null )
    {
        return $this->db->zRange($key, $start, $end ,$withscores);
    }

    /**
     * 返回有序集key中，指定区间内的成员。
     * 其中成员的位置按score值递减(从大到小)来排列。
     * 具有相同score值的成员按字典序的反序(reverse lexicographical order)排列。
     * 下标参数start和stop都以0为底，也就是说，以0表示有序集第一个成员，以1表示有序集第二个成员，以此类推。
     * 你也可以使用负数下标，以-1表示最后一个成员，-2表示倒数第二个成员，以此类推。
     * 超出范围的下标并不会引起错误。
     * 比如说，当start的值比有序集的最大下标还要大，或是start > stop时，ZRANGE命令只是简单地返回一个空列表。
     * 另一方面，假如stop参数的值比有序集的最大下标还要大，那么Redis将stop当作最大下标来处理。
     * 可以通过使用WITHSCORES选项，来让成员和它的score值一并返回，返回列表以value1,score1, ..valueN,scoreN的格式表示。
     * 客户端库可能会返回一些更复杂的数据类型，比如数组、元组等。
     * For example,
     * $re = $redis->zRevRange('ming',0,10);
     *
     * @param $key
     * @param $start
     * @param $end
     * @param $options Two options are available:
     *                      - withscores => TRUE,
     *                      - and limit => array($offset, $count)
     * @return array
     */
    public function zRevRange($key, $start, $end , $withscores = null )
    {
        return $this->db->zRevRange($key, $start, $end ,$withscores);
    }

    /**
     * ZRANGEBYSCORE key min max [WITHSCORES] [LIMIT offset count]
     * 返回有序集key中，所有score值介于min和max之间(包括等于min或max)的成员有序集成员按score值递增(从小到大)次序排列。
     * 具有相同score值的成员按字典序(lexicographical order)来排列(该属性是有序集提供的，不需要额外的计算)。
     * 可选的LIMIT参数指定返回结果的数量及区间(就像SQL中的SELECT LIMIT offset, count)
     * 注意当offset很大时定位offset的操作可能需要遍历整个有序集，此过程最坏复杂度为O(N)时间。
     * 客户端库可能会返回一些更复杂的数据类型，比如数组、元组等。
     * For example,
     * * <pre>
     * $redis->zAdd('key', 0, 'val0');
     * $redis->zAdd('key', 2, 'val2');
     * $redis->zAdd('key', 10, 'val10');
     * $redis->zRangeByScore('key', 0, 3);                                          // array('val0', 'val2')
     * $redis->zRangeByScore('key', 0, 3, array('withscores' => TRUE);              // array('val0' => 0, 'val2' => 2)
     * $redis->zRangeByScore('key', 0, 3, array('limit' => array(1, 1));                        // array('val2' => 2)
     * $redis->zRangeByScore('key', 0, 3, array('limit' => array(1, 1));                        // array('val2')
     * $redis->zRangeByScore('key', 0, 3, array('withscores' => TRUE, 'limit' => array(1, 1));  // array('val2' => 2)
     * $ress = $redis->zRangeByScore('names',0,100,array('withscores' =>true,'limit'=>array(1,10)));
     * @param $key
     * @param $start
     * @param $end
     * @param $options Two options are available:
     *                      - withscores => TRUE,
     *                      - and limit => array($offset, $count)
     * @return array
     */
    public function zRangeByScore($key, $start, $end , $options = array())
    {
        return $this->db->zRangeByScore($key, $start, $end ,$options);
    }

    /**
     * ZREVRANGEBYSCORE key max min [WITHSCORES] [LIMIT offset count]
     * 返回有序集key中，score值介于max和min之间(默认包括等于max或min)的所有的成员。有序集成员按score值递减(从大到小)的次序排列。
     * 具有相同score值的成员按字典序的反序(reverse lexicographical order)排列。
     * 可选的LIMIT参数指定返回结果的数量及区间(就像SQL中的SELECT LIMIT offset, count)
     * 注意当offset很大时定位offset的操作可能需要遍历整个有序集，此过程最坏复杂度为O(N)时间。
     * 客户端库可能会返回一些更复杂的数据类型，比如数组、元组等。
     * For example,
     * * <pre>
     * $redis->zAdd('key', 0, 'val0');
     * $redis->zAdd('key', 2, 'val2');
     * $redis->zAdd('key', 10, 'val10');
     * $redis->zRevRangeByScore('key', 0, 3);                                          // array('val0', 'val2')
     * $redis->zRevRangeByScore('key', 0, 3, array('withscores' => TRUE);              // array('val0' => 0, 'val2' => 2)
     * $redis->zRevRangeByScore('key', 0, 3, array('limit' => array(1, 1));                        // array('val2' => 2)
     * $redis->zRevRangeByScore('key', 0, 3, array('limit' => array(1, 1));                        // array('val2')
     * $redis->zRevRangeByScore('key', 0, 3, array('withscores' => TRUE, 'limit' => array(1, 1));  // array('val2' => 2)
     * $ress = $redis->zRevRangeByScore('names',0,100,array('withscores' =>true,'limit'=>array(1,10)));
     * @param $key
     * @param $start
     * @param $end
     * @param $options Two options are available:
     *                      - withscores => TRUE,
     *                      - and limit => array($offset, $count)
     * @return array
     */
    public function zRevRangeByScore($key, $start, $end , $options = array())
    {
        return $this->db->zRevRangeByScore($key, $start, $end ,$options);
    }

    /**
     * ZCOUNT key min max
     * 返回有序集key中，score值在min和max之间(默认包括score值等于min或max)的成员。
     * For example,
     * $ress = $redis->zCount('names',0,100);
     * @param $key
     * @param $value
     * @return array score值在min和max之间的成员的数量。
     */
    public function zCount( $key, $start, $end )
    {
        return $this->db->zCount( $key, $start, $end );
    }

    /**
     * ZREMRANGEBYRANK key start stop
     * 移除有序集key中，指定排名(rank)区间内的所有成员。
     * 区间分别以下标参数start和stop指出，包含start和stop在内。
     * 下标参数start和stop都以0为底，也就是说，以0表示有序集第一个成员，以1表示有序集第二个成员，以此类推。
     * 你也可以使用负数下标，以-1表示最后一个成员，-2表示倒数第二个成员，以此类推。
     * For example,
     * $ress = $redis->zRemRangeByRank('names',0,100);
     * @param $key
     * @param $value
     * @return string 被移除成员的数量。
     */
    public function zRemRangeByRank( $key, $start, $end )
    {
        return $this->db->zRemRangeByRank( $key, $start, $end );
    }

    /**
     * ZREMRANGEBYSCORE key min max
     * 移除有序集key中，指定排名(rank)区间内的所有成员。
     * 自版本2.1.6开始，score值等于min或max的成员也可以不包括在内
     * 下标参数start和stop都以0为底，也就是说，以0表示有序集第一个成员，以1表示有序集第二个成员，以此类推。
     * 你也可以使用负数下标，以-1表示最后一个成员，-2表示倒数第二个成员，以此类推。
     * For example,
     * $ress = $redis->zRemRangeByScore('names',0,100);
     * @param $key
     * @param $value
     * @return string 被移除成员的数量。
     */
    public function zRemRangeByScore( $key, $start, $end )
    {
        return $this->db->zRemRangeByScore( $key, $start, $end );
    }

    /**
     * ZCARD key
     * 返回有序集key的基数。
     * $ress = $redis->zCard('names');
     * @param $key
     * @return true 当key存在且是有序集类型时，返回有序集的基数。
     *         当key不存在时，返回0。
     */
    public function zCard($key)
    {
        return $this->db->zCard($key);
    }

    /**
     * ZSCORE key member
     * 返回有序集key中，成员member的score值。
     * 如果member元素不是有序集key的成员，或key不存在，返回nil。
     * $ress = $redis->zCard('names');
     * @param $key
     * @return true 当key存在且是有序集类型时，返回有序集的基数。
     *         当key不存在时，返回0。
     */
    public function zScore( $key, $member )
    {
        return $this->db->zScore( $key, $member );
    }

    /**
     * ZRANK key member
     * 返回有序集key中成员member的排名。其中有序集成员按score值递增(从小到大)顺序排列。
     * 排名以0为底，也就是说，score值最小的成员排名为0。
     * 如果member元素不是有序集key的成员，或key不存在，返回nil。
     * $ress = $redis->zRank('names','xiaomings' );
     * @param $key
     * @return true 如果member是有序集key的成员，返回member的排名。如果member不是有序集key的成员，返回nil。
     */
    public function zRank( $key, $member )
    {
        return $this->db->zRank( $key, $member );
    }

    /**
     * ZREVRANK key member
     * 返回有序集key中成员member的排名。其中有序集成员按score值递减(从大到小)排序。
     * 排名以0为底，也就是说，score值最小的成员排名为0。
     * 如果member元素不是有序集key的成员，或key不存在，返回nil。
     * $ress = $redis->zRevRank('names','xiaomings' );
     * @param $key
     * @return true 如果member是有序集key的成员，返回member的排名。如果member不是有序集key的成员，返回nil。
     */
    public function zRevRank( $key, $member )
    {
        return $this->db->zRevRank( $key, $member );
    }

    /**
     * ZINCRBY key increment member
     * 为有序集key的成员member的score值加上增量increment。
     * 你也可以通过传递一个负数值increment，让score减去相应的值，比如ZINCRBY key -5 member，就是让member的score值减去5。
     * 当key不存在，或member不是key的成员时，ZINCRBY key increment member等同于ZADD key increment member。
     * 当key不是有序集类型时，返回一个错误。score值可以是整数值或双精度浮点数。
     * $ress = $redis->zIncrBy( 'names',88, 'xiaomings' );
     * @param $key
     * @param value
     * @param $member
     * @return true member成员的新score值，以字符串形式表示。
     */
    public function zIncrBy( $key, $value, $member )
    {
        return $this->db->zIncrBy( $key, $value, $member );
    }

    /**
     * 取两个集合的并集，合并于集合
     * $ress = $redis->zUnion( 'xiaobin',array('names','namess'));
     * 将集合names和集合namess元素合并于集合xiaobin并且新集合中元素不能重复返回新集合的元素个数如果元素A在tkey和tkey1都存在，则合并后的元素A的score相加
     * $ress = $redis->zUnion( 'xiaobin',array('names','namess'),array(5, 2));
     * 集合k1和集合k2并集于k02 ，array(5,1)中元素的个数与子集合对应，然后 5 对应k1 k1每个元素score都要乘以5 ，同理1对应k2，k2每个元素score乘以1
     * 然后元素按照递增排序，默认相同的元素score(SUM)相加
     * $ress = $redis->zUnion( 'xiaobin',array('names','namess'),array(5, 2),'MAX');
     * 各个子集乘以因子之后，元素按照递增排序，相同的元素的score取最大值(MAX)也可以设置MIN 取最小值
     * @param $key
     * @param value
     * @param $member
     * @return true
     */
    public function zUnion($Output, $ZSetKeys, $Weights = null, $aggregateFunction = 'SUM')
    {
        return $this->db->zUnion($Output, $ZSetKeys, $Weights, $aggregateFunction = 'SUM');
    }

    /**
     * 取两个集合的交集，交于集合
     * $ress = $redis->zInter( 'xiaobin',array('names','namess'));
     * 将集合names和集合namess元素交于集合xiaobin并且新集合中元素不能重复返回新集合的元素个数如果元素A在tkey和tkey1都存在，则合并后的元素A的score相加
     * $ress = $redis->zInter( 'xiaobin',array('names','namess'),array(5, 2));
     * 集合k1和集合k2交集于k02 ，array(5,1)中元素的个数与子集合对应，然后 5 对应k1 k1每个元素score都要乘以5 ，同理1对应k2，k2每个元素score乘以1
     * 然后元素按照递增排序，默认相同的元素score(SUM)相加
     * $ress = $redis->zInter( 'xiaobin',array('names','namess'),array(5, 2),'MAX');
     * 各个子集乘以因子之后，元素按照递增排序，相同的元素的score取最大值(MAX)也可以设置MIN 取最小值
     * @param $key
     * @param value
     * @param $member
     * @return true
     */
    public function zInter($Output, $ZSetKeys, $Weights = null, $aggregateFunction = 'SUM')
    {
        return $this->db->zInter($Output, $ZSetKeys, $Weights, $aggregateFunction = 'SUM');
    }

    /**
     * 排序。无序集合的值只能都是数字，否则不能排序
     * For example
     *
     * @param   string  $key
     * @param   array   $option array(key => value, ...) - optional, with the following keys and values:
     * - 'by' => 'some_pattern_*',  //使用外部key进行排序
     * - 'limit' => array(0, 1),
     * - 'get' => 'some_other_pattern_*' or an array of patterns,   //希望返回的数据
     * - 'sort' => 'asc' or 'desc',
     * - 'alpha' => TRUE,
     * - 'store' => 'external-key'  //如果你希望保存排序结果，可以给STORE选项指定一个key作为参数，排序结果将以列表的形式被保存到这个key上
     * @return true 所有的值
     */
    public function sort($key,$option)
    {
        return $this->db->sort($key,$option);
    }

    /**
     * HSET key field value
     * 将哈希表key中的域field的值设为value。如果key不存在，一个新的哈希表被创建并进行HSET操作。如果域field已经存在于哈希表中，旧值将被覆盖。
     * $ress = $redis->hSet('hash','hash','ssss');
     * @param $key
     * @return 如果field是哈希表中的一个新建域，并且值设置成功，返回1。如果哈希表中域field已经存在且旧值已被新值覆盖，返回0。
     */
    public function hSet( $key, $hashKey, $value )
    {
        return $this->db->hSet( $key, $hashKey, $value );
    }

    /**
     * HSETNX key field value
     * 将哈希表key中的域field的值设置为value，当且仅当域field不存在。若域field已经存在，该操作无效。如果key不存在，一个新哈希表被创建并执行HSETNX命令。
     * $ress = $redis->hSetNx('hash','hash','ssss');
     * @param $key
     * @return 设置成功，返回1。如果给定域已经存在且没有操作被执行，返回0。
     */
    public function hSetNx( $key, $hashKey, $value )
    {
        return $this->db->hSetNx( $key, $hashKey, $value );
    }

    /**
     * HGET key field
     * 返回哈希表key中给定域field的值。
     * $ress = $redis->hGet('hash','hash');
     * @param $key
     * @return 给定域的值。当给定域不存在或是给定key不存在时，返回nil。
     */
    public function hGet($key, $hashKey)
    {
        return $this->db->hGet($key, $hashKey);
    }

    /**
     * HDEL key field [field ...]
     * 删除哈希表key中的一个或多个指定域，不存在的域将被忽略。
     * $ress = $redis->hDel('hash','hash');
     * @param $key
     * @return 被成功移除的域的数量，不包括被忽略的域。
     */
    public function hDel( $key, $hashKey1, $hashKey2 = null)
    {
        return $this->db->hDel( $key, $hashKey1, $hashKey2 );
    }

    /**
     * HKEYS key
     * 返回哈希表key中的所有域。
     * $ress = $redis->hDel('hash','hash');
     * @param $key
     * @return 一个包含哈希表中所有域的表。当key不存在时，返回一个空表。
     */
    public function hKeys( $key )
    {
        return $this->db->hKeys( $key );
    }

    /**
     * HVALS key
     * 返回哈希表key中的所有值。
     * $ress = $redis->hVals('hash');
     * @param $key
     * @return 一个包含哈希表中所有值的表。当key不存在时，返回一个空表。
     */
    public function hVals( $key )
    {
        return $this->db->hVals( $key );
    }

    /**
     * HGETALL key
     * 返回哈希表key中，所有的域和值。在返回值里，紧跟每个域名(field name)之后是域的值(value)，所以返回值的长度是哈希表大小的两倍。
     * $ress = $redis->hGetAll('hash');
     * @param $key
     * @return 以列表形式返回哈希表的域和域的值。 若key不存在，返回空列表。
     */
    public function hGetAll( $key )
    {
        return $this->db->hGetAll( $key );
    }

    /**
     * HEXISTS key field
     * 查看哈希表key中，给定域field是否存在。
     * $ress = $redis->hExists('hash','hash');
     * @param $key
     * @return 如果哈希表含有给定域，返回1。如果哈希表不含有给定域，或key不存在，返回0。
     */
    public function hExists( $key, $hashKey )
    {
        return $this->db->hExists( $key, $hashKey );
    }

    /**
     * HINCRBY key field increment
     * 为哈希表key中的域field的值加上增量increment。增量也可以为负数，相当于对给定域进行减法操作。如果key不存在，一个新的哈希表被创建并执行HINCRBY命令。
     * 如果域field不存在，那么在执行命令前，域的值被初始化为0。对一个储存字符串值的域field执行HINCRBY命令将造成一个错误。
     * $ress = $redis->hIncrBy('hash','hash','zxcz');
     * @param $key
     * @return 执行HINCRBY命令之后，哈希表key中域field的值。
     */
    public function hIncrBy( $key, $hashKey, $value )
    {
        return $this->db->hIncrBy( $key, $hashKey, $value );
    }

    /**
     * hIncrByFloat key field increment
     * 为哈希表key中的域field的值加上增量increment。增量也可以为负数，相当于对给定域进行减法操作。如果key不存在，一个新的哈希表被创建并执行HINCRBY命令。
     * 如果域field不存在，那么在执行命令前，域的值被初始化为0。对一个储存字符串值的域field执行HINCRBY命令将造成一个错误。
     * $ress = $redis->hIncrByFloat('hash','hash',4.5);
     * @param $key
     * @return 执行HINCRBY命令之后，哈希表key中域field的值。
     */
    public function hIncrByFloat( $key, $field, $increment )
    {
        return $this->db->hIncrByFloat( $key, $field, $increment );
    }

    /**
     * HMSET key field value [field value ...]
     * 同时将多个field - value(域-值)对设置到哈希表key中。此命令会覆盖哈希表中已存在的域。如果key不存在，一个空哈希表被创建并执行HMSET操作。
     * 如果域field不存在，那么在执行命令前，域的值被初始化为0。对一个储存字符串值的域field执行HINCRBY命令将造成一个错误。
     * $ress = $redis->hMset('hash', array('name' => 'Joe', 'salary' => 2000));
     * @param $key
     * @param array   $hashKeys key → value array
     * @return 如果命令执行成功，返回OK。当key不是哈希表(hash)类型时，返回一个错误。
     */
    public function hMset( $key, $hashKeys )
    {
        return $this->db->hMset( $key, $hashKeys );
    }

    /**
     * HMGET key field [field ...]
     * 同时将多个field - value(域-值)对设置到哈希表key中。此命令会覆盖哈希表中已存在的域。如果key不存在，一个空哈希表被创建并执行HMSET操作。
     * 如果域field不存在，那么在执行命令前，域的值被初始化为0。对一个储存字符串值的域field执行HINCRBY命令将造成一个错误。
     * $ress = $redis->hMGet('hash', array('name' , 'salary'));
     * @param $key
     * @param array   $hashKeys key → value array
     * @return 如果命令执行成功，返回OK。当key不是哈希表(hash)类型时，返回一个错误。
     */
    public function hMGet( $key, $hashKeys )
    {
        return $this->db->hMGet( $key, $hashKeys );
    }

    /**
     * $redis->multi(Redis::PIPELINE);
     * 标记一个事务块的开始。
     * 事务块内的多条命令会按照先后顺序被放进一个队列当中，最后由 EXEC 命令在一个原子时间内执行。
     */
    public function multi(  )
    {
        return $this->db->multi(  );
    }

    /**
     * 执行所有事务块内的命令。
     * 假如某个(或某些) key 正处于 WATCH 命令的监视之下，且事务块中有和这个(或这些) key 相关的命令，那么 EXEC 命令只在这个(或这些)
     * key没有被其他命令所改动的情况下执行并生效，否则该事务被打断(abort)。
     * 事务块内所有命令的返回值，按命令执行的先后顺序排列。
     * 当操作被打断时，返回空值 nil 。
     */
    public function exec(  )
    {
        return $this->db->exec(  );
    }
}
